package com.syh.jn.scm.infrastructure.repository.impl.operation.system;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AbstractAggregateRepository;
import com.syh.core.expction.DataModelException;
import com.syh.jn.scm.domain.operation.entity.system.Permission;
import com.syh.jn.scm.domain.operation.repository.system.PermissionRepository;
import com.syh.jn.scm.dto.operation.system.permission.PermissionVo;
import com.syh.jn.scm.infrastructure.repository.model.system.PermissionModel;
import com.syh.jn.scm.infrastructure.repository.model.system.PermissionTypeModel;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Repository
public class PermissionRepositoryImpl extends AbstractAggregateRepository<Permission, PermissionModel, Long> implements PermissionRepository {

  @Override
  public Long add(Permission permission) {
    ExtAssert.notNull(permission, "对象不存在");
    ExtAssert.notNull(permission.getTypeId(), "权限分类为空");
    Long typeId = permission.getTypeId();
    PermissionModel model = new PermissionModel();
    PermissionTypeModel type = this.hibernateTemplate.get(PermissionTypeModel.class, typeId);
    if (type == null) {
      throw new DataModelException("权限分类不存在");
    }
    ExtBeanUtils.copyProperties(permission, model);
    return (Long) this.hibernateTemplate.save(model);
  }

	@Override
	@Transactional(propagation =Propagation.REQUIRES_NEW )
	public Long addDtoWithNoCheck(Permission permission) {
  	return super.add(permission);
	}

	@Override
	public void batchDiscardPermission(List<Long> ids) {
		String hql = "UPDATE PermissionModel SET del=-1 WHERE id in (:ids)";
		this.hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(hql).setParameterList("ids", ids).executeUpdate();
	}

	@Override
  public void update(Permission permission) {
    ExtAssert.notNull(permission, "对象不存在");
    Long typeId = permission.getTypeId();
    PermissionModel model = this.hibernateTemplate.get(PermissionModel.class, permission.getId());
    if (permission.getTypeId() != null) {
      PermissionTypeModel type = this.hibernateTemplate.get(PermissionTypeModel.class, typeId);
      if (type == null) {
        throw new DataModelException("权限分类不存在");
      }
    }
    ExtBeanUtils.copyProperties(permission, model, false);
    this.hibernateTemplate.update(model);
  }

  @Override
  public List<Permission> getPermissionByRoleId(Long roleId) {
    String sql = "FROM RoleMenuModel rel INNER JOIN PermissionModel per WITH rel.permissionId = per.id " +
            "WHERE rel.roleId = ? ";
    List<Object[]> list = (List<Object[]>) this.hibernateTemplate.find(sql.toString(), roleId);
    return list.stream().map(object -> {
			Permission permission = new Permission();
			ExtBeanUtils.copyProperties(object[1], permission, false);
			return permission;
		}).collect(Collectors.toList());
  }

  @Override
  public List<Permission> getPermissionBySystemType(Short systemType) {
    String hql = "FROM PermissionTypeModel type INNER JOIN PermissionModel per WITH type.id = per.typeId WHERE type.systemType = ?";
    List<Object[]> list = (List<Object[]>) this.hibernateTemplate.find(hql, systemType);
    return list.stream().map(object -> {
      Permission permission = new Permission();
      ExtBeanUtils.copyProperties(object[1], permission, false);
      return permission;
    }).collect(Collectors.toList());
  }

  @Override
  public List<PermissionVo> getPermissionByMenuId(Long menuId) {
    String hql = "FROM PermissionModel perms INNER JOIN MenuPermissionModel menuPerms WITH perms.id = menuPerms.permissionId WHERE menuPerms.menuId = ?";
    List<Object[]> list = (List<Object[]>) this.hibernateTemplate.find(hql, menuId);
    return list.stream().map(object -> {
      PermissionVo permission = new PermissionVo();
      ExtBeanUtils.copyProperties(object[0], permission, false);
      return permission;
    }).collect(Collectors.toList());
  }

  @Override
  protected Class getViewObject() {
    return PermissionVo.class;
  }

  @Override
  protected SQL getViewSql() {
    return new SQL() {{
      SELECT(
              SQLAliasGenerateUtil.aliasGenerate(PermissionModel.class, "permission", null),
              "type.PERMISSION_TYPE_NAME AS permissionTypeName"
      );
      FROM("T_SYSTEM_PERMISSION permission");
      LEFT_OUTER_JOIN("T_SYSTEM_PERMISSION_TYPE type ON permission.TYPE_ID = type.ID ");
    }};
  }

  @Override
  protected BaseResolve getViewWrapperResolve(Wrapper wrapper) {
    Map<String, String> params = new HashMap<>();
    params.put("terminalType", "permission.TERMINAL_TYPE");
    params.put("permissionName", "permission.PERMISSION_NAME");
    params.put("id", "permission.ID");
    params.put("permissionUrl", "permission.PERMISSION_URL");
    params.put("typeId", "permission.TYPE_ID");
		params.put("del", "permission.DEL");
    ResolveToSQL parse = new ResolveToSQL(wrapper, (propertyName) -> {
      return params.get(propertyName);
    });
    return parse;
  }
}
